package com.wtx.security.filter;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wtx.security.common.RedisConstants;
import com.wtx.security.common.RedisService;
import com.wtx.security.common.ResponseResult;
import com.wtx.security.config.MyUser;
import com.wtx.security.util.JwtUtil;
import com.wtx.security.util.ResponseUtil;
import com.wtx.security.vo.SysUserVO;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;


public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {

    private RedisService redisService;

    public TokenLoginFilter(AuthenticationManager authenticationManager, RedisService redisService) {
        this.redisService = redisService;
        this.setAuthenticationManager(authenticationManager);
        this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/admin/login", "POST"));
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        try {
            SysUserVO sysUserVO = new ObjectMapper().readValue(request.getInputStream(), SysUserVO.class);
            Authentication authenticationToken = new UsernamePasswordAuthenticationToken(sysUserVO.getUsername(), sysUserVO.getPassword());
            return this.getAuthenticationManager().authenticate(authenticationToken);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 登录成功
     *
     * @param request
     * @param response
     * @param chain
     * @param auth
     * @throws IOException
     * @throws ServletException
     */
    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
                                            Authentication auth) throws IOException, ServletException {

        MyUser loginUser = (MyUser) auth.getPrincipal();
        String userId = loginUser.getSysUserVO().getId();
        String token = JwtUtil.createJWT(userId, JwtUtil.JWT_TTL);
        HashMap<String, String> tokenMap = new HashMap<>();
        tokenMap.put("token", token);
        //  以 userId 为key,用户信息为 value 放入缓存
        redisService.getStringRedisTemplate().opsForValue().set(String.format(RedisConstants.USER_KEY_TEMPLATE,userId), JSON.toJSONString(loginUser.getSysUserVO()),30, TimeUnit.MINUTES);

        ResponseUtil.out(response, new ResponseResult(200,"登录成功", tokenMap));
    }

    /**
     * 登录失败
     *
     * @param request
     * @param response
     * @param e
     * @throws IOException
     * @throws ServletException
     */
    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
                                              AuthenticationException e) throws IOException, ServletException {
        ResponseUtil.out(response, new ResponseResult(444, e.getMessage()));
    }

}
